package com.sinszm.wx.pay;

import com.sinszm.common.exception.ApiException;
import com.sinszm.common.util.CamelAndUnderLineConverter;
import com.sinszm.wx.annotation.Required;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付数据格式化
 *
 * @author chenjianbo
 */
public final class PayDataFormat {

    /**
     * 请求数据转换
     * @param reqData   请求数据
     * @param <T>       数据泛型
     * @return          map数据
     */
    public static <T> Map<String, String> reqData(T reqData) {
        Map<String, String> result = new HashMap<>(0);
        if (reqData == null) {
            return result;
        }
        Class<?> clz = reqData.getClass();
        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object data = field.get(reqData);
                //验证数据
                Required required = field.getAnnotation(Required.class);
                if (required != null && data == null) {
                    throw new ApiException("PAY-DATA-ERROR", field.getName() + "数据不能为空.");
                }
                //数据组装
                if (data != null) {
                    result.put(CamelAndUnderLineConverter.humpToLine(field.getName()), String.valueOf(data));
                }
            } catch (Exception e) {
                if (e instanceof ApiException) {
                    throw (ApiException)e;
                }
                e.printStackTrace(System.err);
            }
        }
        return result;
    }

    /**
     * 响应数据转换
     * @param respData  响应map数据
     * @param tClass    转换类型
     * @param <T>       数据泛型
     * @return          目标对象数据
     */
    public static <T> T respData(Map<String, String> respData, Class<T> tClass) {
        if (respData == null || respData.isEmpty()) {
            return null;
        }
        if (tClass == null) {
            return null;
        }
        try {
            T t = tClass.newInstance();
            Field[] fields = tClass.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String key = CamelAndUnderLineConverter.humpToLine(field.getName());
                if (respData.containsKey(key)) {
                    if (field.getGenericType().toString().contains("Integer")) {
                        field.set(t, Integer.valueOf(respData.get(key)));
                    } else if (field.getGenericType().toString().contains("Long")) {
                        field.set(t, Long.valueOf(respData.get(key)));
                    } else {
                        field.set(t, respData.get(key));
                    }
                }
                //原始返回数据进行附加输出
                if ("rawData".equals(field.getName())) {
                    field.set(t, respData);
                }
            }
            return t;
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
        return null;
    }

}
